﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using FacebookWrapper.ObjectModel;

namespace B12_Ex03_Eran_053094363_Assaf_036722999
{
    /// <summary>
    /// Implementing Proxy Pattern
    /// </summary>
    public class FacebookObjectProxy
    {
        private User m_LoggedInUser;

        public FacebookObjectProxy(User i_LoggedInUser)
        {
            m_LoggedInUser = i_LoggedInUser;
        }

        /// <summary>
        /// Function to compare a facebook user
        /// The comparison is made by Name
        /// </summary>
        /// <param name="i_FBUser1">First Facebook User</param>
        /// <param name="i_FBUser2">Second Facebook User</param>
        /// <returns>Comparison Result</returns>
        private int fbUserComparer(User i_FBUser1, User i_FBUser2)
        {
            return i_FBUser1.Name.CompareTo(i_FBUser2.Name);
        }

        /// <summary>
        /// Returns a List of Facebook user Friends
        /// of the input user
        /// </summary>
        /// <param name="i_FBUser">The Facebook User to look for its friends</param>
        /// <returns></returns>
        private List<User> getFBUserFriends(User i_FBUser)
        {
            List<User> retFriendsList = new List<User>();

            try
            {
                retFriendsList = i_FBUser.Friends.ToList();
            }
            catch (Exception)
            {
                // Some Facebook users dont allow the application
                // to access thier friends - this throws an error that we want to ignore
            }

            // Sort the Collection
            retFriendsList.Sort(new Comparison<User>(fbUserComparer));

            return retFriendsList;
        }

        /// <summary>
        /// Returns a List of Facebook User Posts
        /// of the input user
        /// </summary>
        /// <param name="i_FBUser">The Facebook User to look for its posts</param>
        /// <returns></returns>
        private List<Post> getFBUserPosts(User i_FBUser)
        {
            List<Post> retPostsList = new List<Post>();
            try
            {
                retPostsList = i_FBUser.Posts.ToList();
            }
            catch (Exception)
            {
                // Some Facebook users dont allow the application
                // to access thier posts - this throws an error that we want to ignore
            }

            return retPostsList;
        }

        /// <summary>
        /// Get all The Logged on User Friends
        /// </summary>
        /// <returns>A List of Facebook <see cref="User"/> Friends of the Logged on User</returns>
        public List<User> GetFriends()
        {
            List<User> retFriendsList = FacebookListGenerator<User>.GenerateList(() => m_LoggedInUser.Friends);

            // Sort the Collection
            retFriendsList.Sort(new Comparison<User>(fbUserComparer));
            
            // Return the Generated Friedns List as a sorted list
            return retFriendsList;
        }

        /// <summary>
        /// Get all the Friends of the Logged on user and thier friends also
        /// </summary>
        /// <returns>A List of Facebook <see cref="User"/> friends of the Logged on Usr and thier Friends also</returns>
        public List<User> GetFriendsOfFriends()
        {
            List<User> retFriendsOfFriendsList = new List<User>();
            List<User> myFriends = GetFriends();

            foreach (User friend in myFriends)
            {
                // Add all the Friends to the Friends of Friends List
                retFriendsOfFriendsList.AddRange(FacebookListGenerator<User>.GenerateList(() => friend.Friends));
            }

            // Add the Current Logged on User Friends to the List as well
            retFriendsOfFriendsList.AddRange(myFriends);

            // Returns the List with no Duplicate Friends
            return retFriendsOfFriendsList.Distinct().ToList();
        }

        /// <summary>
        /// Get all the Logged on User Events
        /// </summary>
        /// <returns>A List of Facebook <see cref="Event"/> of the Logged on User</returns>
        public List<Event> GetEvents()
        {
            // Return the Generated Event List
            return FacebookListGenerator<Event>.GenerateList(() => m_LoggedInUser.Events);
        }

        /// <summary>
        /// Get the Logged on Facebook User News Feed
        /// </summary>
        /// <returns>A List of string News Feed Messages</returns>
        public NewsFeed GetNewsFeed()
        {
            // Return the Generated List
            return new NewsFeed(FacebookListGenerator<Post>.GenerateList(() => m_LoggedInUser.NewsFeed));
        }

        /// <summary>
        /// Get all The Logged on User Check in
        /// </summary>
        /// <returns>A List of Facebook <see cref="Checkin"/> of the Logged on User</returns>
        public List<Checkin> GetCheckIns()
        {
            // Return the Generated List
            return FacebookListGenerator<Checkin>.GenerateList(() => m_LoggedInUser.Checkins);
        }

        /// <summary>
        /// Get all the Friends Posts
        /// </summary>
        /// <returns></returns>
        public List<Post> GetFriendsPost(int i_PostsCount)
        {
            List<Post> retPostsList = new List<Post>();

            foreach (User friend in GetFriends())
            {
                // Add the Generated User Post List
                retPostsList.AddRange(FacebookListGenerator<Post>.GenerateList(() => friend.Posts.Take(i_PostsCount)));
            }

            return retPostsList;
        }
    }
}
